package com.mingweicai.intergration.springaop.demo2;

import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class FourAdviceAspect {

  @Pointcut("execution(public int com.mingweicai.intergration.springaop.demo2.BusinessService.*(..))")
  public void pointCut(){}

  /**
   * 前置增强
   */
  @Before("pointCut()")
  public void before(JoinPoint joinPoint){
    System.out.println("------@Before: 模拟执行权限检查------");
    System.out.println("------@Before: 执行的方法名"+ joinPoint.getSignature().getName() +"------");
    System.out.println("------@Before: 方法执行的参数"+ Arrays.toString(joinPoint.getArgs()) +"------");
    System.out.println("------@Before: 目标对象"+ joinPoint.getTarget() +"------");
  }

  /**
   * 后置增强
   */
  @After("pointCut()")
  public void after(JoinPoint joinPoint){
    System.out.println("------@After: 方法结束后释放资源------");
    System.out.println("------@After: 执行的方法名"+ joinPoint.getSignature().getName() +"------");
    System.out.println("------@After: 方法执行的参数"+ Arrays.toString(joinPoint.getArgs()) +"------");
    System.out.println("------@After: 目标对象"+ joinPoint.getTarget() +"------");
  }

  /**
   * 返回增强
   * 只有方法成功返回才会执行
   * @param result
   */
  @AfterReturning(value = "pointCut()", returning = "result")
  public void logReturn(JoinPoint joinPoint,Object result){
    System.out.println("------@AfterReturning: 方法结束后释放资源------");
    System.out.println("------@AfterReturning: 执行的方法名"+ joinPoint.getSignature().getName() +"------");
    System.out.println("------@AfterReturning: 方法执行的参数"+ Arrays.toString(joinPoint.getArgs()) +"------");
    System.out.println("------@AfterReturning: 目标对象"+ joinPoint.getTarget() +"------");
    System.out.println("------@AfterReturning: 方法执行的结果"+ result +"------");
  }

  /**
   * 环绕增强
   * @param proceedingJoinPoint
   * @return
   * @throws Throwable
   */
  @Around("pointCut()")
  public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("------@Around: 执行目标方法之前, 模拟开始事务...------");
    Object args[] = proceedingJoinPoint.getArgs();
    if(args != null && args.length > 0 && args[0].getClass() == String.class){
      // 修改目标方法中的第一个参数
      args[0] = "[增加的前缀]:" + args[0];
    }
    Object obj = proceedingJoinPoint.proceed(args);//相当于开始调div地
    System.out.println("------@Around: 执行目标方法之后, 模拟结束事务...------");
    if(obj != null && obj instanceof Integer){
      obj = (Integer) obj * (Integer) obj;
    }
    return obj;
  }

  /**
   * 环绕增强
   * @param proceedingJoinPoint
   * @return
   * @throws Throwable
   */
  @Around("pointCut()")
  public Object around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("------@Around: 执行目标方法之前1, 模拟开始事务...------");
    Object args[] = proceedingJoinPoint.getArgs();
    if(args != null && args.length > 0 && args[0].getClass() == String.class){
      // 修改目标方法中的第一个参数
      args[0] = "[增加的前缀]:" + args[0];
    }
    Object obj = proceedingJoinPoint.proceed(args);//相当于开始调div地
    System.out.println("------@Around: 执行目标方法之后1, 模拟结束事务...------");
    if(obj != null && obj instanceof Integer){
      obj = (Integer) obj * (Integer) obj;
    }
    return obj;
  }
}
